package com.pig4cloud.pigx.wallet.websocket.subscribe;

import com.alibaba.fastjson.JSONObject;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.pig4cloud.pigx.wallet.vo.AbstractTopicVO;
import org.springframework.web.socket.TextMessage;
import org.springframework.web.socket.WebSocketSession;

import java.util.*;
import java.util.concurrent.ConcurrentHashMap;

/**
 */
public abstract class DataListAbstractTopic {

	protected String TOPICNAME = "";
	public Map<WebSocketSession, AbstractTopicVO> subList = new ConcurrentHashMap<>();

	/**
	 * 将会话添加到订阅列表
	 *
	 * @param session  会话
	 * @param newParam 新参数
	 * @since 2022/9/25 17:34
	 */
	protected void add(WebSocketSession session, AbstractTopicVO newParam) {
		// 用户没有订阅过，直接加入订阅列表
		if (!this.subList.containsKey(session)) {
			this.subList.put(session, newParam);
			return;
		}

		// 订阅过
		AbstractTopicVO oldParam = this.subList.get(session);

		// 比较新旧参数
		List<String> newDataList = newParam.getDataList();
		List<String> oldDataList = oldParam.getDataList();
		// 比较新旧参数的数量，如果不同，直接替换并结束
		if (newDataList.size() != oldDataList.size()) {
			this.subList.put(session, newParam);
			return;
		}

		// 比较新旧参数的值
		for (int i = 0; i < newDataList.size(); i++) {
			String newData = newDataList.get(i);
			String oldData = oldDataList.get(i);

			// 如果有任意参数不一致，直接替换
			if (!Objects.equals(newData, oldData)) {
				this.subList.put(session, newParam);
				break;
			}
		}
	}

	/**
	 * 将会话移出订阅列表
	 *
	 * @param session 会话
	 * @since 2022/9/25 17:35
	 */
	protected void remove(WebSocketSession session) {
		this.subList.remove(session);
	}

	/**
	 * 订阅
	 *
	 * @param session 会话
	 * @param params  参数
	 * @since 2022/9/25 17:34
	 */
	public AbstractTopicVO sub(WebSocketSession session, List<String> params) {
		// 转换参数为vo
		AbstractTopicVO vo = new AbstractTopicVO();
		vo.setDataList(params);

		// 将会话添加到订阅列表
		add(session, vo);
		return vo;
	}

	/**
	 * 取消订阅
	 *
	 * @param session 会话
	 * @since 2022/9/25 17:42
	 */
	public void unsub(WebSocketSession session, List<String> params) {
		// 将会话移出订阅列表
		remove(session);
	}

	public TextMessage getTextMessage(Object type, Object data) {
		JSONObject object = new JSONObject();
		object.put("params", type);
		object.put("data", data);
		try {
			ObjectMapper objectMapper = new ObjectMapper();
			String asString = objectMapper.writeValueAsString(object);
			return new TextMessage(asString);
		} catch (Exception e) {
			return new TextMessage(object.toJSONString());
		}
	}
}
